// InputEngine.cpp

#include <iostream>
#include "../include/InputEngine.hpp"
#include "../include/Common.hpp"
namespace OForce_Input {

InputEngine *InputEngine::m_pInstance = NULL;

InputEngine *InputEngine::Instance()
{
	if (m_pInstance == NULL) {
		m_pInstance = new InputEngine;
	}
	return m_pInstance;
}

InputEngine::InputEngine() : anyKeyPressed(false),
				anyKeyReleased(false),
				upState(false),
				downState(false),
				leftState(false),
				rightState(false),
				menuState(false),
				cancelState(false),
				actionState(false),
				upPress(false),
				downPress(false),
				leftPress(false),
				rightPress(false),
				menuPress(false),
				cancelPress(false),
				actionPress(false),
				upReleased(false),
				downReleased(false),
				leftReleased(false),
				rightReleased(false),
				menuReleased(false),
				cancelReleased(false),
				actionReleased(false),
				quitPress(false) {
	// set default keys:
	// TODO get from user defined file if it exists
	mKey.action = sf::Keyboard::C;
	mKey.cancel = sf::Keyboard::X;
	mKey.down   = sf::Keyboard::Down;
	mKey.left   = sf::Keyboard::Left;
	mKey.menu   = sf::Keyboard::Z;
	mKey.right  = sf::Keyboard::Right;
	mKey.up     = sf::Keyboard::Up;
}

void InputEngine::EventHandler(sf::Event Event) {
	// Reset all flags
	anyKeyPressed = false;
	anyKeyReleased = false;
	upPress = false;
	downPress = false; 
	leftPress = false;
	rightPress = false;
	menuPress = false;
	cancelPress = false;
	actionPress = false;
	upReleased = false;
	downReleased = false;
	leftReleased = false;
	rightReleased = false;
	menuReleased = false; 
	cancelReleased = false;
	actionReleased = false;
	if (Event.type == sf::Event::Closed ||
		Event.key.code == sf::Keyboard::Escape) {
		quitPress = true;
	} else if (Event.type == sf::Event::KeyPressed ||
			Event.type == sf::Event::KeyReleased) {
		keyHandler(Event);
	} else if (Event.type == sf::Event::JoystickButtonPressed ||
			Event.type == sf::Event::JoystickButtonReleased) {
		std::cout << "Debug joystick: " << Event.joystickButton.joystickId
				<< " " << Event.joystickButton.button << "\r";
		joyHandler(Event);
	}
}

void InputEngine::keyHandler(sf::Event Event) {
	if (Event.type == sf::Event::KeyPressed) {
		anyKeyPressed = true;
		// Each of these should be set to a redefinable variable instead of sfml keycodes
		if (Event.key.code == mKey.up) {
			upState = true;
			upPress = true;
		}
		if (Event.key.code == mKey.down) {
			downState = true;
			downPress = true;
		}
		if (Event.key.code == mKey.left) {
			leftState = true;
			leftPress = true;
		}
		if (Event.key.code == mKey.right) {
			rightState = true;
			rightPress = true;
		}
		if (Event.key.code == mKey.menu) {
			menuState = true;
			menuPress = true;
		}
		if (Event.key.code == mKey.cancel) {
			cancelState = true;
			cancelPress = true;
		}
		if (Event.key.code == mKey.action) {
			actionState = true;
			actionPress = true;
		}
	} else { // key released
		anyKeyPressed = false;
		anyKeyReleased = true;
        if (Event.key.code == mKey.up) {
			upState = false;
			upReleased = true;
        }
        if (Event.key.code == mKey.down) {
			downState = false;
			downReleased = true;
        }
        if (Event.key.code == mKey.left) {
			leftState = false;
			leftReleased = true;
        }
        if (Event.key.code == mKey.right) {
			rightState = false;
			rightReleased = true;
        }
        if (Event.key.code == mKey.menu) {
			menuState = false;
			menuReleased = true;
        }
        if (Event.key.code == mKey.cancel) {
			cancelState = false;
			cancelReleased = true;
        }
        if (Event.key.code == mKey.action) {
			actionState = false;
			actionReleased = true;
		}
	}
}

void InputEngine::joyHandler(sf::Event Event) {
	if (Event.type == sf::Event::JoystickButtonPressed) {
		anyKeyPressed = true;
		if (sf::Joystick::isButtonPressed(0, mJoy.up)) {
			upState = true;
			upPress = true;
		} else if (sf::Joystick::isButtonPressed(0, mJoy.down)) {
			downState = true;
			downPress = true;				
		} else if (sf::Joystick::isButtonPressed(0, mJoy.left)) {
			leftState = true;
			leftPress = true;
		} else if (sf::Joystick::isButtonPressed(0, mJoy.right)) { 
			rightState = true;
			rightPress = true;
		} else if (sf::Joystick::isButtonPressed(0, mJoy.menu)) {
			menuState = true;
			menuPress = true;
		} else if (sf::Joystick::isButtonPressed(0, mJoy.cancel)) {
			cancelState = true;
			cancelPress = true;
		} else if (sf::Joystick::isButtonPressed(0, mJoy.action)) {
			actionState = true;
			actionPress = true;
		}
	} else { // button released
		anyKeyPressed = false;
		anyKeyReleased = true;
		if (Event.joystickButton.button == mJoy.up) {
			upState = false;
			upReleased = true;
		} else if (Event.joystickButton.button == mJoy.down) {
			downState = false;
			downReleased = true;
		} else if (Event.joystickButton.button == mJoy.left) {
			leftState = false;
			leftReleased = true;
		} else if (Event.joystickButton.button == mJoy.right) {
			rightState = false;
			rightReleased = true;
		} else if (Event.joystickButton.button == mJoy.menu) {
			menuState = false;
			menuReleased = true;
		} else if (Event.joystickButton.button == mJoy.cancel) {
			cancelState = false;
			cancelReleased = true;
		} else if (Event.joystickButton.button == mJoy.action) {
			actionState = false;
			actionReleased = true;
		}
	}
}

void InputEngine::setNewKey(sf::Keyboard::Key &oldKey, sf::Keyboard::Key newKey) {
	// Do not allow the escape button to be redefined
	if (newKey == sf::Keyboard::Escape) {
		return;
	}
	// If key is already used, swap them around
	if ( mKey.up == newKey) {
		mKey.up = oldKey;
		oldKey = newKey;
		return;
	} else if ( mKey.down == newKey) {
		mKey.down = oldKey;
		oldKey = newKey;
		return;
	} else if ( mKey.left == newKey) {
		mKey.left = oldKey;
		oldKey = newKey;
		return;
	} else if ( mKey.right == newKey) {
		mKey.right = oldKey;
		oldKey = newKey;
		return;
	} else if ( mKey.menu == newKey) {
		mKey.menu = oldKey;
		oldKey = newKey;
		return;
	} else if ( mKey.cancel == newKey) {
		mKey.cancel = oldKey;
		oldKey = newKey;
		return;
	} else if ( mKey.action == newKey) {
		mKey.action = oldKey;
		oldKey = newKey;
		return;
	} 
	// If we have gotten here, key was previously unused
	oldKey = newKey;
}

} // namespace OForce_Input
